#include <stdio.h>
#include <stdlib.h>
#include <dlfcn.h>
#include "strategy.h"
#include <time.h>
#include <unistd.h> // for getpid()

void *handleA = NULL;
void *handleB = NULL;
strategy_func pickA = NULL;
strategy_func pickB = NULL;

int main(int argc, char *argv[])
{
    if (argc < 4)
    {
        fprintf(stderr, "用法：%s [初始硬币数] [玩家A策略.so] [玩家B策略.so]\n", argv[0]);
        return 1;
    }
    int initial_coins = atoi(argv[1]);
    // 如果输入0，则随机初始硬币数（例如10~29）
    if (initial_coins == 0)
    {
        srand(time(NULL) ^ getpid());
        initial_coins = (rand() % 20) + 10; // 随机范围10~29
        printf("随机初始硬币：%d", initial_coins);
    }
    
    // TODO：装入动态库到句柄handleA和handleB
    handleA = dlopen(argv[2], RTLD_NOW);
    handleB = dlopen(argv[3], RTLD_NOW);    
    if (!handleA || !handleB)
    {
        fprintf(stderr, "动态库打开失败: %s\n", dlerror());
        return 1;
    }

    // TODO：绑定函数指针，分别赋值给pickA和pickB
    pickA = (strategy_func)dlsym(handleA, "pick_coins");
    pickB = (strategy_func)dlsym(handleB, "pick_coins");

    if(!pickA || !pickB){
	fprintf(stderr, "函数绑定失败: %s\n", dlerror());
	return 1;
    }
    int round = 1;
    int coins = initial_coins;
    int last_pick_A = 0, last_pick_B = 0;

    // 分配可读写状态区，每策略各64字节
    void *mem = malloc(STATE_SIZE * 2);
    void *stateA = mem;
    void *stateB = mem + STATE_SIZE;

    printf("比赛开始，初始硬币：%d\n", initial_coins);
    while (coins > 0)
    {
        int pick;
        if (round % 2 == 1)
        {
            pick = pickA(round, initial_coins, last_pick_B, stateA, STATE_SIZE);
            printf("[A] 第 %d 轮，剩余 %d 枚，A 取 %d。\n", round, coins, pick);
            last_pick_A = pick;
        }
        else
        {
            pick = pickB(round, initial_coins, last_pick_A, stateB, STATE_SIZE);
            printf("[B] 第 %d 轮，剩余 %d 枚，B 取 %d。\n", round, coins, pick);
            last_pick_B = pick;
        }
        if (pick < 1 || pick > 3 || pick > coins)
        {
            printf("非法操作，%s 失败！\n", (round % 2 == 1) ? "A" : "B");
            printf("%s 赢得比赛！\n", (round % 2 == 0) ? "A" : "B");
            break;
        }
        coins -= pick;
        if (coins == 0)
        {
            printf("%s 赢得比赛！\n", (round % 2 == 1) ? "A" : "B");
            break;
        }
        round++;
    }
    
    // TODO：关闭动态库
    dlclose(handleA);
    dlclose(handleB);
    free(mem);
    return 0;
}
